import {NumberUtil} from "../../utils/NumberUtil";

export class Orientation {

  static anglePerRadian: number = 180 / Math.PI;


  /**
   * 角度,以12点钟方向为0度
   */
  angle: number;

  constructor(angle: number) {
    this.angle = angle;
  }

  /**
   * 弧度,以12点钟方向为0度
   */
  getRadian(): number {
    return this.angle / Orientation.anglePerRadian;
  }

  copy(): Orientation {
    return new Orientation(this.angle);
  }

  /**
   * 确保角度在0-360度之内
   */
  normalize() :Orientation{
    if (0 <= this.angle && this.angle < 360) {
      return this;
    }

    let ang = NumberUtil.resolved(this.angle % 360);
    if (ang < 0) {
      this.angle = 360 + ang;
    } else {
      this.angle = ang;
    }
    return this;
  }

  /**
   * 以指定步长转向目标角度
   * @param target 目标角度
   * @param rotateAngleStep 转动的角度 必须>0
   */
  rotateToTarget(target: Orientation, rotateAngleStep: number) {
    this.normalize();
    target.normalize();

    //还需要移动的偏移量
    let move = target.angle - this.angle;

    //切换到更近的转动方向 使得计算Math.abs(move)<180
    if (move > 0) {
      if (Math.abs(move) > 180) {
        this.angle += 360;//目标在前面，加一圈
        move = target.angle - this.angle;
      }
    }else{
      if (Math.abs(move) > 180) {
        this.angle -= 360;//目标在后面，减一圈
        move = target.angle - this.angle;
      }
    }


    if (move == 0) {
      return;
    }
    //符号化
    const signifyingAngle = move > 0 ? rotateAngleStep : -rotateAngleStep;
    //单次转动的角度小于偏移量，则只转动指定的角度
    if (rotateAngleStep <= Math.abs(move)) {
      this.angle += signifyingAngle;
    } else {
      //直接设定到目标角度
      this.angle = target.angle;
    }
    this.normalize();
  }


  static distanceOfAngle(a1:Orientation,a2:Orientation):number{
    return Math.abs(a1.copy().normalize().angle-a2.copy().normalize().angle)
  }
}



